/*
 * main.c
 *
 *  Created on: 2009-8-7
 *      Author: wyb
 */

#include "util.h"
#include "fft.h"
#include "log.h"
#include "history.h"
#include "xengine_mysql.h"

int main(int argc, char * argv[]) {

	set_project_name("xengine_task");

	xengine_mysql_init(URL, DB, USERNAME, PASSWORD);

	struct app_array *apps = get_apps();

	int app_i;
	for (app_i = 0; app_i < apps->N; app_i++) {

		printf("%s\n", apps->data[app_i].app_name);

		//从数据库中获取历史数据
		struct double_array *history = get_history(apps->data[app_i].id, "cpu");

		if (history->N < LIMIT_NUM * 2) {
			//将周期清0
			update_app_period(apps->data[app_i].id, 0.0);
			free(history->data);
			free(history);
			continue;
		}

		//历史数据去除异常点
		history_filter(history);

		//历史数据做fft
		struct fft_complex *history_complex = real_to_complex(history);
		struct fft_complex *history_fft_complex = fft(history_complex);
		struct fft_cosine *history_fft_cosine = complex_to_cosine(
				history_fft_complex);

		printf("分析历史数据\n");
		//分析历史数据，得出周期
		struct double_array *periods = analyze_history(history_fft_cosine,
				history->N);
		output_double_array(periods, "周期图法分析出的各个周期");
		printf("分析历史数据完成\n");

		//判断是否有周期存在
		if (periods != NULL) {

			double useful_period = 0.0;
			if (periods->N == 1) {
				useful_period = periods->data[0];
			} else {
				int i, j;
				double min = -1.0;
				printf("比较周期：\n");
				for (i = 0; i < periods->N; i++) {
					double period = periods->data[i];
					printf("周期：%lf\n", period);
					double error = 0.0;

					int len = ((int) period) * MIN_FREQUENCY / 2;
					if (len < LIMIT_NUM) {
						len = LIMIT_NUM;
					}
					for (j = len; j < history->N; j++) {
						struct double_array *current;
						current = malloc(sizeof(struct double_array));
						current->N = len;
						current->data = malloc(current->N * sizeof(double));
						int k;
						for (k = 0; k < current->N; k++) {
							current->data[k] = history->data[k + j - len];
						}
						struct fft_complex *current_complex = real_to_complex(
								current);
						struct fft_complex *current_fft_complex = fft(
								current_complex);
						struct fft_cosine *current_fft_cosine =
								complex_to_cosine(current_fft_complex);

						double temp = compute_conine(current_fft_cosine,
								current->N, period, current->N - 1);
						double percent = history->data[j - 1] / temp;
						temp = compute_conine(current_fft_cosine, current->N,
								period, current->N);
						error += pow(history->data[j] - temp * percent, 2);

						free(current);
						free(current_complex);
						free(current_fft_complex);
						free(current_fft_cosine);
					}

					error = error / history->N;
					printf("error：%f\n", error);
					if (error < min || min < 0.0) {
						min = error;
						useful_period = period;
					}
				}
			}
			printf("最终周期：%lf\n", useful_period);

			//将周期写入数据库
			update_app_period(apps->data[app_i].id, useful_period);
		} else {
			//将周期清0
			update_app_period(apps->data[app_i].id, 0.0);
		}

		//释放资源
		free(history->data);
		free(history);
		free(history_complex->data);
		free(history_complex);
		free(history_fft_complex->data);
		free(history_fft_complex);
		free(history_fft_cosine->A);
		free(history_fft_cosine);
	}
	xengine_mysql_close();

	return 0;
}
